package 尚硅谷juc大厂.test15;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicMarkableReference;

/**
 * AtomicMarkableReference：是一次性的，多线程下只能有一个线程执行成功
 * 它通过标记的true/false来控制是否有人改动了原子引用
 * 下面构造方法传入2个参数，第一个是初始的引用值，第二个是初始的标记
 * AtomicMarkableReference markableReference=new AtomicMarkableReference(100,false);
 * AtomicMarkableReference就是通过对比标记来实现线程安全的
 * isMarked()：是否被标记了，true就是被标记了，false是未被标记过(未被修改过)
 */
public class Test15 {
    static AtomicMarkableReference markableReference=new AtomicMarkableReference(100,false);
    public static void main(String[] args) throws InterruptedException {

        new Thread(()->{
            /**
             * 获取当前标记的值
             */
            boolean marked = markableReference.isMarked();
            System.out.println(Thread.currentThread().getName()+"\t"+"执行修改标志");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            /**
             * 比较并更新
             * 返回值为true则修改成功，否则修改失败
             * compareAndSet：比较并更新
             * 第一个参数：初始的原子值
             * 第二个参数：修改的值
             * 第三个参数：初始的原子标记
             * 第四个参数：修改后的标记
             */
            boolean b = markableReference.compareAndSet(100, 101, marked, !marked);
        },"t1").start();

        new Thread(()->{
            /**
             * 获取当前标记的值
             */
            boolean marked = markableReference.isMarked();
            System.out.println(Thread.currentThread().getName()+"\t"+"执行修改标志");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            /**
             * 比较并更新
             */
            boolean b = markableReference.compareAndSet(100, 200, marked, !marked);
            System.out.println(b?"t2线程操作成功":"t2线程操作失败");
        },"t2").start();
        TimeUnit.SECONDS.sleep(5);
        System.out.println("最终的数据是："+markableReference.getReference());
    }
}
